package com.tsfyun.scm.service.impl.customer;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Snowflake;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.tsfyun.common.base.config.OrikaBeanMapper;
import com.tsfyun.common.base.exception.ServiceException;
import com.tsfyun.common.base.security.SecurityUtil;
import com.tsfyun.common.base.util.StringUtils;
import com.tsfyun.common.base.util.TsfPreconditions;
import com.tsfyun.scm.dto.customer.SupplierTakeInfoDTO;
import com.tsfyun.scm.dto.customer.SupplierTakeInfoQTO;
import com.tsfyun.scm.dto.customer.client.ClientSupplierTakeInfoQTO;
import com.tsfyun.scm.entity.customer.Supplier;
import com.tsfyun.scm.entity.customer.SupplierTakeInfo;
import com.tsfyun.scm.mapper.customer.SupplierTakeInfoMapper;
import com.tsfyun.scm.service.customer.ISupplierService;
import com.tsfyun.scm.service.customer.ISupplierTakeInfoService;
import com.tsfyun.common.base.extension.ServiceImpl;
import com.tsfyun.scm.util.PermissionUtil;
import com.tsfyun.scm.util.TsfWeekendSqls;
import com.tsfyun.scm.vo.customer.SupplierTakeInfoListVO;
import com.tsfyun.scm.vo.customer.SupplierTakeInfoVO;
import com.tsfyun.scm.vo.customer.client.ClientSupplierTakeInfoVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.weekend.WeekendSqls;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *

 * @since 2020-03-12
 */
@Service
public class SupplierTakeInfoServiceImpl extends ServiceImpl<SupplierTakeInfo> implements ISupplierTakeInfoService {

    @Autowired
    private OrikaBeanMapper beanMapper;

    @Autowired
    private SupplierTakeInfoMapper supplierTakeInfoMapper;

    @Autowired
    private ISupplierService supplierService;

    @Autowired
    private Snowflake snowflake;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addBatch(Long supplierId, List<SupplierTakeInfoDTO> takes) {
        if(CollectionUtil.isEmpty(takes)) {
            return;
        }
        //设置第一个启用的为默认
        Boolean isDefault = false;
        for(int i=0;i<takes.size();i++){
            SupplierTakeInfoDTO supplierTakeInfoDTO = takes.get(i);
            if(supplierTakeInfoDTO.getIsDefault()
               && supplierTakeInfoDTO.getDisabled() != true){
                isDefault=true;
            }
        }
        if(isDefault==false){
            for(int i=0;i<takes.size();i++){
                SupplierTakeInfoDTO supplierTakeInfoDTO = takes.get(i);
                if(supplierTakeInfoDTO.getDisabled() != true) {
                    takes.get(i).setIsDefault(Boolean.TRUE);
                }
            }
        }
        List<SupplierTakeInfo> supplierTakeInfos = Lists.newArrayList();
        takes.stream().forEach(dto->{
            SupplierTakeInfo r = new SupplierTakeInfo();
            r.setId(snowflake.nextId());
            r.setSupplierId(supplierId);
            //去特殊字符
            r.setCompanyName(StringUtils.removeSpecialSymbol(dto.getCompanyName()));
            r.setLinkPerson(StringUtils.removeSpecialSymbol(dto.getLinkPerson()));
            r.setLinkTel(StringUtils.removeSpecialSymbol(dto.getLinkTel()));
            r.setProvinceName(StringUtils.removeSpecialSymbol(dto.getProvinceName()));
            r.setCityName(StringUtils.removeSpecialSymbol(dto.getCityName()));
            r.setAreaName(StringUtils.removeSpecialSymbol(dto.getAreaName()));
            r.setAddress(StringUtils.removeSpecialSymbol(dto.getAddress()));
            r.setDisabled(dto.getDisabled());
            r.setIsDefault(dto.getIsDefault());
            r.setDateCreated(LocalDateTime.now());
            r.setDateUpdated(r.getDateCreated());
            r.setCreateBy(SecurityUtil.getCurrentPersonIdAndName());
            r.setUpdateBy(r.getCreateBy());
            supplierTakeInfos.add(r);
        });
        super.savaBatch(supplierTakeInfos);
    }

    @Override
    public List<SupplierTakeInfo> list(Long supplierId) {
        SupplierTakeInfo supplierTakeInfo = new SupplierTakeInfo();
        supplierTakeInfo.setSupplierId(supplierId);
        return super.list(supplierTakeInfo);
    }

    @Override
    public void removeBySupplierId(Long supplierId) {
        supplierTakeInfoMapper.deleteByExample(Example.builder(SupplierTakeInfo.class).where(TsfWeekendSqls.<SupplierTakeInfo>custom().andEqualTo(false,SupplierTakeInfo::getSupplierId,supplierId)).build());
    }

    @Override
    public SupplierTakeInfoVO detail(Long id) {
        SupplierTakeInfo supplierTakeInfo = super.getById(id);
        TsfPreconditions.checkArgument(Objects.nonNull(supplierTakeInfo),new ServiceException("供应商提货信息不存在"));
        SupplierTakeInfoVO vo = beanMapper.map(supplierTakeInfo,SupplierTakeInfoVO.class);
        //供应商名称
        vo.setSupplierName(supplierService.get(vo.getSupplierId()).getName());
        return vo;
    }

    @Override
    public List<SupplierTakeInfoVO> select(Long supplierId) {
        List<SupplierTakeInfo> suppliers =  super.list(new SupplierTakeInfo().setSupplierId(supplierId).setDisabled(Boolean.FALSE));
        //先按是否默认提货信息排序，然后按修改时间排序
        suppliers = suppliers.stream().sorted(Comparator.comparing(SupplierTakeInfo::getIsDefault).thenComparing(SupplierTakeInfo::getDateUpdated).reversed()).collect(Collectors.toList());
        return beanMapper.mapAsList(suppliers,SupplierTakeInfoVO.class);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void setDefault(Long id) {
        //无需前台传参，后台根据数据库的记录取反
        SupplierTakeInfo supplierTakeInfo = super.getById(id);
        TsfPreconditions.checkArgument(Objects.nonNull(supplierTakeInfo),new ServiceException("供应商提货信息不存在"));
        Boolean currentDefault = supplierTakeInfo.getIsDefault();
        if(Objects.equals(Boolean.TRUE,currentDefault)) {
            //以前是默认，则现在无需操作
            return;
        } else {
            //以前是非默认，现在置为默认，则需要取消以前的默认如果存在的话
            supplierTakeInfo.setIsDefault(Boolean.TRUE);
            supplierTakeInfo.setDisabled(Boolean.FALSE);
            handleOldDefault(supplierTakeInfo.getSupplierId());
            super.updateById(supplierTakeInfo);
        }
    }

    @Override
    public void handleOldDefault(Long supplierId) {
        SupplierTakeInfo update = new SupplierTakeInfo();
        update.setIsDefault(Boolean.FALSE);
        supplierTakeInfoMapper.updateByExampleSelective(update, Example.builder(SupplierTakeInfo.class).where(WeekendSqls.<SupplierTakeInfo>custom()
                .andEqualTo(SupplierTakeInfo::getSupplierId, supplierId)
                .andEqualTo(SupplierTakeInfo::getIsDefault,Boolean.TRUE)).build());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long add(SupplierTakeInfoDTO dto) {
        TsfPreconditions.checkArgument(Objects.nonNull(dto.getSupplierId()),new ServiceException("请选择供应商"));
        Supplier supplier = supplierService.getById(dto.getSupplierId());
        TsfPreconditions.checkArgument(Objects.nonNull(supplier),new ServiceException("供应商信息不存在"));
        SupplierTakeInfo supplierTakeInfo = beanMapper.map(dto,SupplierTakeInfo.class);
        //是否默认处理
        if(Objects.equals(dto.getIsDefault(),Boolean.TRUE)) {
            //取消以前设置的是否默认
            handleOldDefault(supplier.getId());
        }
        if(Objects.equals(Boolean.TRUE,dto.getIsDefault())) {
            supplierTakeInfo.setDisabled(Boolean.FALSE);
        }
        super.saveNonNull(supplierTakeInfo);
        return supplierTakeInfo.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long clientAdd(SupplierTakeInfoDTO dto) {
        TsfPreconditions.checkArgument(StringUtils.isNotEmpty(dto.getSupplierName()),new ServiceException("请选择供应商"));
        Supplier supplier = supplierService.findByCustomerIdAndSupplierName(SecurityUtil.getCurrentCustomerId(),dto.getSupplierName());
        TsfPreconditions.checkArgument(Objects.nonNull(supplier),new ServiceException("供应商信息不存在"));
        dto.setSupplierId(supplier.getId());
        dto.setDisabled(Boolean.FALSE);
        return add(dto);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(SupplierTakeInfoDTO dto) {
        TsfPreconditions.checkArgument(Objects.nonNull(dto.getId()),new ServiceException("请选择要修改的数据"));
        TsfPreconditions.checkArgument(Objects.nonNull(dto.getSupplierId()),new ServiceException("请选择供应商"));
        Supplier supplier = supplierService.getById(dto.getSupplierId());
        TsfPreconditions.checkArgument(Objects.nonNull(supplier),new ServiceException("供应商信息不存在"));
        SupplierTakeInfo oldSupplierTakeInfo = super.getById(dto.getId());
        TsfPreconditions.checkArgument(Objects.nonNull(oldSupplierTakeInfo),new ServiceException("供应商提货信息不存在"));
        SupplierTakeInfo supplierTakeInfo = beanMapper.map(dto,SupplierTakeInfo.class);
        supplierTakeInfo.setDateCreated(oldSupplierTakeInfo.getDateCreated());
        supplierTakeInfo.setCreateBy(oldSupplierTakeInfo.getCreateBy());
        //如果由非默认变为默认则需要处理之前设置的默认的，如果是否默认未变更则无需处理
        if (!oldSupplierTakeInfo.getIsDefault() && supplierTakeInfo.getIsDefault()) {
            handleOldDefault(supplier.getId());
        }
        if(Objects.equals(Boolean.TRUE,dto.getIsDefault())) {
            supplierTakeInfo.setDisabled(Boolean.FALSE);
        }
        super.updateById(supplierTakeInfo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void clientEdit(SupplierTakeInfoDTO dto) {
        TsfPreconditions.checkArgument(StringUtils.isNotEmpty(dto.getSupplierName()),new ServiceException("请选择供应商"));
        Supplier supplier = supplierService.findByCustomerIdAndSupplierName(SecurityUtil.getCurrentCustomerId(),dto.getSupplierName());
        TsfPreconditions.checkArgument(Objects.nonNull(supplier),new ServiceException("供应商信息不存在"));
        dto.setSupplierId(supplier.getId());
        edit(dto);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateDisabled(Long id, Boolean disabled) {
        SupplierTakeInfo supplierTakeInfo = super.getById(id);
        TsfPreconditions.checkArgument(Objects.nonNull(supplierTakeInfo),new ServiceException("供应商提货信息不存在"));
        SupplierTakeInfo update = new SupplierTakeInfo();
        update.setDisabled(disabled);
        update.setIsDefault(Boolean.FALSE);
        supplierTakeInfoMapper.updateByExampleSelective(update, Example.builder(SupplierTakeInfo.class).where(
                WeekendSqls.<SupplierTakeInfo>custom().andEqualTo(SupplierTakeInfo::getId,id)
        ).build());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void remove(Long id) {
        SupplierTakeInfo supplierTakeInfo = super.getById(id);
        TsfPreconditions.checkArgument(Objects.nonNull(supplierTakeInfo),new ServiceException("供应商提货信息不存在"));
        //删除供应商提货信息，数据冗余到具体的业务表
        super.removeById(id);
    }

    @Override
    public int countBySupplierId(Long supplierId) {
        return supplierTakeInfoMapper.selectCountByExample(Example.builder(SupplierTakeInfo.class).where(TsfWeekendSqls.<SupplierTakeInfo>custom().andEqualTo(true,SupplierTakeInfo::getSupplierId,supplierId)).build());
    }

    @Override
    public PageInfo<SupplierTakeInfoListVO> pageList(SupplierTakeInfoQTO qto) {
        PageHelper.startPage(qto.getPage(),qto.getLimit());
        Map<String,Object> params = beanMapper.map(qto,Map.class);
        return new PageInfo<>(supplierTakeInfoMapper.list(params));
    }

    @Override
    public List<SupplierTakeInfoListVO> effectiveList(SupplierTakeInfoQTO qto) {
        if(StringUtils.isNotEmpty(qto.getCustomerName())&&StringUtils.isNotEmpty(qto.getSupplierName())){
            Map<String,Object> params = beanMapper.map(qto,Map.class);
            return supplierTakeInfoMapper.effectiveList(params);

        }
        return Lists.newArrayList();
    }

    @Override
    public PageInfo<ClientSupplierTakeInfoVO> clientPage(ClientSupplierTakeInfoQTO qto) {
        PageHelper.startPage(qto.getPage(),qto.getLimit());
        List<ClientSupplierTakeInfoVO> list = supplierTakeInfoMapper.clientPage(qto);
        return new PageInfo(list);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void clientRemove(Long id) {
        SupplierTakeInfo supplierTakeInfo = super.getById(id);
        Optional.ofNullable(supplierTakeInfo).orElseThrow(()->new ServiceException("供应商提货信息不存在，请确认是否已经被删除"));
        Supplier supplier = supplierService.getById(supplierTakeInfo.getSupplierId());
        PermissionUtil.checkClientCustomerPermission(supplier);
        super.removeById(id);
    }
}
